﻿using System;
using System.Linq;
using PH.Model.Achievements;
namespace PH.Data.Statistics
{
    public class MarkCommand
    {
        public static void CreateMarks(MarkCollection models)
        {
            if (models != null && models.Count>0)
            {
                using (DBCentre db = new DBCentre())
                {
                    if (string.IsNullOrEmpty(models[0].StudentNo)) throw new Utils.PhException("没有身份证号");
                    if (models[0].SchoolGuid == Guid.Empty) throw new Utils.PhException("没有学校信息");

                    var sGuid = models[0].SchoolGuid;
                    var studentNo = models[0].StudentNo;
                    var stu = db.DataContext.Students.FirstOrDefault(p => p.School.Guid ==sGuid && p.StudentNo == studentNo);
                    if (stu == null) throw new Utils.PhException("没有找到学生");
                    
                    foreach (var model in models)
                    {
                        model.SchoolID = stu.SchoolID;
                        model.GradeCode = stu.Class.GradeCode;
                        model.ClassID = stu.ClassID;
                        model.StudentID = stu.ID;
                        model.Sex = stu.Sex;
                        model.ClassName = stu.Class.ClassName;

                        if (model.Subject.Sex != 0 && model.Sex != model.Subject.Sex)
                            throw new Utils.PhException(string.Format("项目\"{0}\"与学生的性别不符。", model.Subject.SubjectName));
                        if (!model.AutoPass && (model.Achievement < model.Subject.Min || model.Achievement > model.Subject.Max))
                            throw new Utils.PhException(string.Format("成绩超出项目\"{0}\"的许可范围。",model.Subject.SubjectName));
                        
                        switch (model.Subject.Category)
                        {
                            case 1:
                                ScoreCompute.BMI(db, model);
                                break;
                            case 2:
                                ScoreCompute.Distance(db, model);
                                break;
                            case 3:
                            case 4:
                                ScoreCompute.Speed(db, model);
                                break;
                            default:
                                throw new Utils.PhException("未规定的项目种类");
                        }
                        var dMark = db.DataContext.Marks.FirstOrDefault(p => p.ArchiveGuid == model.ArchiveGuid && p.SchoolID == model.SchoolID && p.StudentID == model.StudentID && p.SubjectID == model.SubjectID);
                        if (dMark != null)
                            db.DataContext.Marks.Remove(dMark);
                        var newMark = Convertor.ConvertFrom<Mark, MarkModel>(model);
                        db.DataContext.Marks.Add(newMark);
                    }

                    db.DataContext.SaveChanges();
                }
            }
        }

        public static void Update(int id,string newmark)
        {
            if (id>0)
            {
                using (DBCentre db = new DBCentre())
                {
                    var d = db.DataContext.Marks.FirstOrDefault(p => p.ID == id);
                    if (d != null)
                    {
                        var model = Convertor.ConvertTo<MarkModel, Mark>(d);
                        model.Subject = Convertor.ConvertTo<Model.Standards.SubjectModel, Subject>(d.Subject);

                        #region 成绩转换标准数字
                        if (model.Subject.Category == 3)
                        {
                            newmark = System.Text.RegularExpressions.Regex.Replace(newmark, @"['`‘′]", ".");
                            newmark = System.Text.RegularExpressions.Regex.Replace(newmark, "[ “\"]", "");
                            var index = newmark.IndexOf(".");
                            if (index > 0)
                            {
                                var minute = decimal.Parse(newmark.Substring(0, index).Trim());
                                decimal second = 0;
                                if (!string.IsNullOrEmpty(newmark.Substring(2).Trim()))
                                    second = decimal.Parse(newmark.Substring(2).Trim());
                                model.Achievement = minute * 60 + second;
                            }
                            else
                                model.Achievement = decimal.Parse(newmark);
                        }
                        else
                            model.Achievement = decimal.Parse(newmark);
                        #endregion

                        if (model.Achievement < model.Subject.Min || model.Achievement > model.Subject.Max)
                            throw new Utils.PhException("成绩超出此项目的许可范围。");

                        switch (model.Subject.Category)
                        {
                            case 1:
                                ScoreCompute.BMI(db, model);
                                break;
                            case 2:
                                ScoreCompute.Distance(db, model);
                                break;
                            case 3:
                            case 4:
                                ScoreCompute.Speed(db, model);
                                break;
                            default:
                                throw new Utils.PhException("未规定的项目种类");
                        }

                        Convertor.UpdateValue(model, d);
                        db.DataContext.SaveChanges();
                    }
                }
            }
        }

        public static MarkCollection Gets(MarkQuery sea)
        {
            var ret = new MarkCollection();
            if (sea != null)
            {
                var n = 0;
                using (DBCentre db = new DBCentre())
                {
                    IQueryable<Mark> q = db.DataContext.Marks;
                    if (sea.ArchiveGuid != Guid.Empty)
                        q = q.Where(p => p.ArchiveGuid == sea.ArchiveGuid);
                    if (sea.SchoolGuid != Guid.Empty)
                        q = q.Where(p => p.School.Guid == sea.SchoolGuid);
                    if (sea.ClassID > 0)
                        q = q.Where(p => p.ClassID == sea.ClassID);
                    if (sea.SubjectID > 0)
                        q = q.Where(p => p.SubjectID == sea.SubjectID);
                    if (sea.Sex > 0)
                        q = q.Where(p => p.Sex == sea.Sex);
                    if (sea.StudentGuid != Guid.Empty)
                        q = q.Where(p => p.Student.Guid == sea.StudentGuid);
                    if (sea.StudentID > 0)
                        q = q.Where(p => p.StudentID == sea.StudentID);
                    if (sea.AutoPass != null)
                        q = q.Where(p => p.AutoPass == sea.AutoPass.Value);
                    if (!string.IsNullOrEmpty(sea.Key))
                        q = q.Where(p => p.Student.RealName == sea.Key || p.Student.StudentNo == sea.Key);
                    
                    if (sea.OrderBy != null)
                    {
                        switch (sea.OrderBy.Field)
                        {
                            case "Score":
                                if (sea.OrderBy.Dir == "asc")
                                    q = q.OrderBy(p => p.Score);
                                else
                                    q = q.OrderByDescending(p => p.Score);
                                break;
                            default:
                                q = q.OrderBy(p => p.ClassID).ThenBy(p => p.SubjectID);
                                break;
                        }
                    }else
                        q = q.OrderBy(p => p.ClassID).ThenBy(p => p.SubjectID);

                    if (sea.PageSize > 0)
                    {
                        n = q.Count();
                        q = q.Skip(sea.PageSize * sea.PageIndex).Take(sea.PageSize);
                    }

                    var lst = q.ToList();
                    ret = Convertor.ConvertCollection<MarkModel, Mark, MarkCollection>(lst);
                    ret.TotalRecordsCount = n == 0 ? lst.Count : n;
                    ret.ForEach(p =>
                    {
                        var d = lst.Find(o => o.ID == p.ID);
                        if (sea.GetClassName)
                            p.ClassName = d.Class.ClassName;
                        if (sea.GetStudentName)
                            p.StudentName = d.Student.RealName;
                        if (sea.GetSchoolName)
                            p.SchoolName = d.Student.School.SchoolName;
                        if (sea.GetSubject)
                            p.Subject = Convertor.ConvertTo<Model.Standards.SubjectModel, Subject>(d.Subject);
                    });
                }
            }
            return ret;
        }

        public static MarkModel GetModel(int id)
        {
            if (id > 0)
            {
                using (DBCentre db = new DBCentre())
                {
                    var d = db.DataContext.Marks.FirstOrDefault(p => p.ID == id);
                    if (d != null)
                    {
                        var ret = Convertor.ConvertTo<MarkModel, Mark>(d);
                        ret.ClassName = d.Class.ClassName;
                        ret.StudentNo = d.Student.StudentNo;
                        ret.StudentName = d.Student.RealName;
                        ret.SchoolName = d.Student.School.SchoolName;
                        ret.Subject = Convertor.ConvertTo<Model.Standards.SubjectModel, Subject>(d.Subject);
                        return ret;
                    }
                }
            }
            return null;
        }

        public static void CopyMarks(Guid sGuid, Guid tGuid, Guid schGuid)
        {
            if (sGuid == Guid.Empty)
                throw new Utils.PhException("请提供源档案");
            if (tGuid == Guid.Empty)
                throw new Utils.PhException("请提供目标档案");
            if (schGuid == Guid.Empty)
                throw new Utils.PhException("没有学校");

            using (DBCentre db = new DBCentre())
            {
                var sch = db.DataContext.Schools.FirstOrDefault(p => p.Guid == schGuid);
                if (sch==null)
                    throw new Utils.PhException("无效的学校。");
                
                db.DataContext.CopyMarks(sGuid, tGuid, sch.ID);
            }
        }
    }
}
